Add description to the character sheet skills.

This commit is contained in:
Thomas Andres Gomez 2024-11-29 00:15:19 +01:00
parent 4606122264
commit 95122d2c99
14 changed files with 265 additions and 151 deletions

View file

@ -47,6 +47,7 @@
<string name="character_sheet_edit__skills__special_action">Ajouter une compétence spéciale</string> <string name="character_sheet_edit__skills__special_action">Ajouter une compétence spéciale</string>
<string name="character_sheet_edit__skills__magic_title">Compétences magiques</string> <string name="character_sheet_edit__skills__magic_title">Compétences magiques</string>
<string name="character_sheet_edit__skills__magic_action">Ajouter une compétence magique</string> <string name="character_sheet_edit__skills__magic_action">Ajouter une compétence magique</string>
<string name="character_sheet_edit__skills__description_label">Description</string>
<string name="character_sheet_edit__skills__base_label">Base</string> <string name="character_sheet_edit__skills__base_label">Base</string>
<string name="character_sheet_edit__skills__bonus_label">Bonus</string> <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__level_label">Niveau</string>

View file

@ -9,6 +9,7 @@ import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetJsonFactory import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetJsonFactory
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetStore import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetStore
import com.pixelized.desktop.lwa.repository.characterSheet.SkillDescriptionFactory
import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetFactory import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetFactory
@ -50,6 +51,7 @@ val factoryDependencies
factoryOf(::CharacterSheetJsonFactory) factoryOf(::CharacterSheetJsonFactory)
factoryOf(::NetworkFactory) factoryOf(::NetworkFactory)
factoryOf(::SkillFieldFactory) factoryOf(::SkillFieldFactory)
factoryOf(::SkillDescriptionFactory)
} }
val viewModelDependencies val viewModelDependencies

View file

@ -5,11 +5,30 @@ import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJson import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJson
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJsonV1 import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJsonV1
import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__acrobatics
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__aid
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__athletics
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__bargain
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__combat
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__discretion
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__dodge
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__empathy
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__grab
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__intimidation
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__perception
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__persuasion
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__search
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__sleight_of_hand
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__spiel
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__throw
import org.jetbrains.compose.resources.getString
import kotlin.math.ceil import kotlin.math.ceil
class CharacterSheetJsonFactory( class CharacterSheetJsonFactory(
private val bonusDamageUseCase: DamageBonusUseCase, private val bonusDamageUseCase: DamageBonusUseCase,
private val arithmeticParser: ArithmeticParser, private val skillDescriptionFactory: SkillDescriptionFactory,
) { ) {
fun convertToJson( fun convertToJson(
@ -36,6 +55,7 @@ class CharacterSheetJsonFactory(
CharacterSheetJsonV1.Skill( CharacterSheetJsonV1.Skill(
id = it.id, id = it.id,
label = it.label, label = it.label,
description = null,
base = it.base, base = it.base,
bonus = it.bonus, bonus = it.bonus,
level = it.level, level = it.level,
@ -47,6 +67,7 @@ class CharacterSheetJsonFactory(
CharacterSheetJsonV1.Skill( CharacterSheetJsonV1.Skill(
id = it.id, id = it.id,
label = it.label, label = it.label,
description = it.description,
base = it.base, base = it.base,
bonus = it.bonus, bonus = it.bonus,
level = it.level, level = it.level,
@ -58,6 +79,7 @@ class CharacterSheetJsonFactory(
CharacterSheetJsonV1.Skill( CharacterSheetJsonV1.Skill(
id = it.id, id = it.id,
label = it.label, label = it.label,
description = it.description,
base = it.base, base = it.base,
bonus = it.bonus, bonus = it.bonus,
level = it.level, level = it.level,
@ -76,7 +98,7 @@ class CharacterSheetJsonFactory(
return json return json
} }
fun convertFromJson( suspend fun convertFromJson(
json: CharacterSheetJson, json: CharacterSheetJson,
): CharacterSheet { ): CharacterSheet {
return when (json) { return when (json) {
@ -84,7 +106,7 @@ class CharacterSheetJsonFactory(
} }
} }
private fun convertFromV1( private suspend fun convertFromV1(
json: CharacterSheetJsonV1, json: CharacterSheetJsonV1,
): CharacterSheet { ): CharacterSheet {
val sheet = CharacterSheet( val sheet = CharacterSheet(
@ -117,6 +139,7 @@ class CharacterSheetJsonFactory(
CharacterSheet.Skill( CharacterSheet.Skill(
id = it.id, id = it.id,
label = it.label, label = it.label,
description = skillDescriptionFactory.baseSkillDescription(id = json.id),
base = it.base, base = it.base,
bonus = it.bonus, bonus = it.bonus,
level = it.level, level = it.level,
@ -128,6 +151,7 @@ class CharacterSheetJsonFactory(
CharacterSheet.Skill( CharacterSheet.Skill(
id = it.id, id = it.id,
label = it.label, label = it.label,
description = it.description,
base = it.base, base = it.base,
bonus = it.bonus, bonus = it.bonus,
level = it.level, level = it.level,
@ -139,6 +163,7 @@ class CharacterSheetJsonFactory(
CharacterSheet.Skill( CharacterSheet.Skill(
id = it.id, id = it.id,
label = it.label, label = it.label,
description = it.description,
base = it.base, base = it.base,
bonus = it.bonus, bonus = it.bonus,
level = it.level, level = it.level,

View file

@ -3,8 +3,12 @@ package com.pixelized.desktop.lwa.repository.characterSheet
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJson import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheetJson
import com.pixelized.desktop.lwa.repository.characterStorePath import com.pixelized.desktop.lwa.repository.characterStorePath
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.io.File import java.io.File
@ -13,7 +17,15 @@ class CharacterSheetStore(
private val factory: CharacterSheetJsonFactory, private val factory: CharacterSheetJsonFactory,
) { ) {
private val characterDirectory = File(characterStorePath()).also { it.mkdirs() } private val characterDirectory = File(characterStorePath()).also { it.mkdirs() }
private val flow = MutableStateFlow(value = load()) private val jsonFormatter: Json = Json { explicitNulls = false }
private val flow = MutableStateFlow<List<CharacterSheet>>(value = emptyList())
init {
val scope = CoroutineScope(Dispatchers.IO + Job())
scope.launch {
flow.value = load()
}
}
fun characterSheetFlow(): StateFlow<List<CharacterSheet>> = flow fun characterSheetFlow(): StateFlow<List<CharacterSheet>> = flow
@ -25,7 +37,7 @@ class CharacterSheetStore(
fun save(sheet: CharacterSheet) { fun save(sheet: CharacterSheet) {
// convert the character sheet into json format. // convert the character sheet into json format.
val json = try { val json = try {
factory.convertToJson(sheet = sheet).let(Json::encodeToString) factory.convertToJson(sheet = sheet).let(jsonFormatter::encodeToString)
} catch (exception: Exception) { } catch (exception: Exception) {
throw JsonConversionException(root = exception) throw JsonConversionException(root = exception)
} }
@ -72,7 +84,7 @@ class CharacterSheetStore(
FileReadException::class, FileReadException::class,
JsonConversionException::class, JsonConversionException::class,
) )
fun load(): List<CharacterSheet> { suspend fun load(): List<CharacterSheet> {
return characterDirectory return characterDirectory
.listFiles() .listFiles()
?.mapNotNull { file -> ?.mapNotNull { file ->
@ -86,7 +98,7 @@ class CharacterSheetStore(
return@mapNotNull null return@mapNotNull null
} }
try { try {
val sheet = Json.decodeFromString<CharacterSheetJson>(json) val sheet = jsonFormatter.decodeFromString<CharacterSheetJson>(json)
factory.convertFromJson(sheet) factory.convertFromJson(sheet)
} catch (exception: Exception) { } catch (exception: Exception) {
throw JsonConversionException(root = exception) throw JsonConversionException(root = exception)

View file

@ -0,0 +1,47 @@
package com.pixelized.desktop.lwa.repository.characterSheet
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__acrobatics
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__aid
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__athletics
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__bargain
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__combat
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__discretion
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__dodge
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__empathy
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__grab
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__intimidation
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__perception
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__persuasion
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__search
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__sleight_of_hand
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__spiel
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__throw
import org.jetbrains.compose.resources.getString
class SkillDescriptionFactory {
suspend fun baseSkillDescription(id: String): String? {
return when (id) {
CharacterSheet.CommonSkillId.COMBAT_ID -> getString(Res.string.tooltip__skills__combat)
CharacterSheet.CommonSkillId.DODGE_ID -> getString(Res.string.tooltip__skills__dodge)
CharacterSheet.CommonSkillId.GRAB_ID -> getString(Res.string.tooltip__skills__grab)
CharacterSheet.CommonSkillId.THROW_ID -> getString(Res.string.tooltip__skills__throw)
CharacterSheet.CommonSkillId.ATHLETICS_ID -> getString(Res.string.tooltip__skills__athletics)
CharacterSheet.CommonSkillId.ACROBATICS_ID -> getString(Res.string.tooltip__skills__acrobatics)
CharacterSheet.CommonSkillId.PERCEPTION_ID -> getString(Res.string.tooltip__skills__perception)
CharacterSheet.CommonSkillId.SEARCH_ID -> getString(Res.string.tooltip__skills__search)
CharacterSheet.CommonSkillId.EMPATHY_ID -> getString(Res.string.tooltip__skills__empathy)
CharacterSheet.CommonSkillId.PERSUASION_ID -> getString(Res.string.tooltip__skills__persuasion)
CharacterSheet.CommonSkillId.INTIMIDATION_ID -> getString(Res.string.tooltip__skills__intimidation)
CharacterSheet.CommonSkillId.SPIEL_ID -> getString(Res.string.tooltip__skills__spiel)
CharacterSheet.CommonSkillId.BARGAIN_ID -> getString(Res.string.tooltip__skills__bargain)
CharacterSheet.CommonSkillId.DISCRETION_ID -> getString(Res.string.tooltip__skills__discretion)
CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.tooltip__skills__sleight_of_hand)
CharacterSheet.CommonSkillId.AID_ID -> getString(Res.string.tooltip__skills__aid)
else -> null
}
}
}

View file

@ -34,6 +34,7 @@ data class CharacterSheet(
data class Skill( data class Skill(
val id: String, val id: String,
val label: String, val label: String,
val description: String?,
val base: String, val base: String,
val bonus: Int?, val bonus: Int?,
val level: Int?, val level: Int?,
@ -48,21 +49,21 @@ data class CharacterSheet(
) )
object CommonSkillId { object CommonSkillId {
const val COMBAT_ID = "Bagarre" const val COMBAT_ID = "COMBAT"
const val DODGE_ID = "Esquive" const val DODGE_ID = "DODGE"
const val GRAB_ID = "Saisie" const val GRAB_ID = "GRAB"
const val THROW_ID = "Lancer" const val THROW_ID = "THROW"
const val ATHLETICS_ID = "Athlétisme" const val ATHLETICS_ID = "ATHLETICS"
const val ACROBATICS_ID = "Acrobatie" const val ACROBATICS_ID = "ACROBATICS"
const val PERCEPTION_ID = "Perception" const val PERCEPTION_ID = "PERCEPTION"
const val SEARCH_ID = "Recherche" const val SEARCH_ID = "SEARCH"
const val EMPATHY_ID = "Empathie" const val EMPATHY_ID = "EMPATHY"
const val PERSUASION_ID = "Persuasion" const val PERSUASION_ID = "PERSUASION"
const val INTIMIDATION_ID = "Intimidation" const val INTIMIDATION_ID = "INTIMIDATION"
const val SPIEL_ID = "Baratin" const val SPIEL_ID = "SPIEL"
const val BARGAIN_ID = "Marchandage" const val BARGAIN_ID = "BARGAIN"
const val DISCRETION_ID = "Discrétion" const val DISCRETION_ID = "DISCRETION"
const val SLEIGHT_OF_HAND_ID = "Escamotage" const val SLEIGHT_OF_HAND_ID = "SLEIGHT_OF_HAND"
const val AID_ID = "Premiers soins" const val AID_ID = "AID"
} }
} }

View file

@ -31,10 +31,12 @@ data class CharacterSheetJsonV1(
// attack // attack
val rolls: List<Roll>, val rolls: List<Roll>,
) : CharacterSheetJson { ) : CharacterSheetJson {
@Serializable @Serializable
data class Skill( data class Skill(
val id: String, val id: String,
val label: String, val label: String,
val description: String?,
val base: String, val base: String,
val bonus: Int?, val bonus: Int?,
val level: Int?, val level: Int?,

View file

@ -2,8 +2,8 @@ package com.pixelized.desktop.lwa.screen.characterSheet.detail
import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase
import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio
import com.pixelized.desktop.lwa.repository.characterSheet.SkillDescriptionFactory
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Node import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Node
import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.Res
@ -26,22 +26,6 @@ import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__intelligence import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__intelligence
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__power import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__power
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__strength import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__strength
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__acrobatics
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__aid
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__athletics
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__bargain
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__combat
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__discretion
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__dodge
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__empathy
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__grab
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__intimidation
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__perception
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__persuasion
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__search
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__sleight_of_hand
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__spiel
import lwacharactersheet.composeapp.generated.resources.tooltip__skills__throw
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__armor import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__armor
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__bonus_damage import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__bonus_damage
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hit_point import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hit_point
@ -51,6 +35,7 @@ import org.jetbrains.compose.resources.getString
class CharacterSheetFactory( class CharacterSheetFactory(
private val skillUseCase: SkillValueComputationUseCase, private val skillUseCase: SkillValueComputationUseCase,
private val skillDescriptionFactory: SkillDescriptionFactory,
) { ) {
companion object { companion object {
const val HP = "HP" const val HP = "HP"
@ -189,25 +174,6 @@ class CharacterSheetFactory(
), ),
), ),
commonSkills = sheet.commonSkills.map { skill -> commonSkills = sheet.commonSkills.map { skill ->
val description = when (skill.id) {
CommonSkillId.COMBAT_ID -> getString(Res.string.tooltip__skills__combat)
CommonSkillId.DODGE_ID -> getString(Res.string.tooltip__skills__dodge)
CommonSkillId.GRAB_ID -> getString(Res.string.tooltip__skills__grab)
CommonSkillId.THROW_ID -> getString(Res.string.tooltip__skills__throw)
CommonSkillId.ATHLETICS_ID -> getString(Res.string.tooltip__skills__athletics)
CommonSkillId.ACROBATICS_ID -> getString(Res.string.tooltip__skills__acrobatics)
CommonSkillId.PERCEPTION_ID -> getString(Res.string.tooltip__skills__perception)
CommonSkillId.SEARCH_ID -> getString(Res.string.tooltip__skills__search)
CommonSkillId.EMPATHY_ID -> getString(Res.string.tooltip__skills__empathy)
CommonSkillId.PERSUASION_ID -> getString(Res.string.tooltip__skills__persuasion)
CommonSkillId.INTIMIDATION_ID -> getString(Res.string.tooltip__skills__intimidation)
CommonSkillId.SPIEL_ID -> getString(Res.string.tooltip__skills__spiel)
CommonSkillId.BARGAIN_ID -> getString(Res.string.tooltip__skills__bargain)
CommonSkillId.DISCRETION_ID -> getString(Res.string.tooltip__skills__discretion)
CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.tooltip__skills__sleight_of_hand)
CommonSkillId.AID_ID -> getString(Res.string.tooltip__skills__aid)
else -> null
}
Node( Node(
label = skill.label, label = skill.label,
value = skillUseCase.computeSkillValue( value = skillUseCase.computeSkillValue(
@ -215,7 +181,7 @@ class CharacterSheetFactory(
skill = skill, skill = skill,
diminished = diminished, diminished = diminished,
), ),
tooltips = description?.let { tooltips = skillDescriptionFactory.baseSkillDescription(id = skill.id)?.let {
TooltipUio( TooltipUio(
title = skill.label, title = skill.label,
description = it, description = it,
@ -224,26 +190,38 @@ class CharacterSheetFactory(
used = skill.used, used = skill.used,
) )
}, },
specialSKills = sheet.specialSkills.map { specialSKills = sheet.specialSkills.map { skill ->
Node( Node(
label = it.label, label = skill.label,
tooltips = skill.description?.takeIf { it.isNotBlank() }?.let { description ->
TooltipUio(
title = skill.label,
description = description,
)
},
value = skillUseCase.computeSkillValue( value = skillUseCase.computeSkillValue(
sheet = sheet, sheet = sheet,
skill = it, skill = skill,
diminished = diminished, diminished = diminished,
), ),
used = it.used, used = skill.used,
) )
}, },
magicsSkills = sheet.magicSkills.map { magicsSkills = sheet.magicSkills.map { skill ->
Node( Node(
label = it.label, label = skill.label,
tooltips = skill.description?.takeIf { it.isNotBlank() }?.let { description ->
TooltipUio(
title = skill.label,
description = description,
)
},
value = skillUseCase.computeSkillValue( value = skillUseCase.computeSkillValue(
sheet = sheet, sheet = sheet,
skill = it, skill = skill,
diminished = diminished, diminished = diminished,
), ),
used = it.used, used = skill.used,
) )
}, },
actions = sheet.actions.mapNotNull { actions = sheet.actions.mapNotNull {

View file

@ -1,6 +1,7 @@
package com.pixelized.desktop.lwa.screen.characterSheet.detail package com.pixelized.desktop.lwa.screen.characterSheet.detail
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.SizeTransform import androidx.compose.animation.SizeTransform
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
@ -446,47 +447,55 @@ fun CharacterSheetPageContent(
} }
} }
} }
DecoratedBox( AnimatedVisibility(
modifier = Modifier visible = characterSheet.specialSKills.isNotEmpty()
.fillMaxWidth()
.padding(vertical = 8.dp),
) { ) {
Column { DecoratedBox(
Text( modifier = Modifier
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp), .fillMaxWidth()
style = MaterialTheme.typography.caption, .padding(vertical = 8.dp),
textAlign = TextAlign.Center, ) {
text = stringResource(Res.string.character_sheet__skills__special_title), Column {
) Text(
characterSheet.specialSKills.forEach { occupation -> modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp),
Skill( style = MaterialTheme.typography.caption,
modifier = Modifier.cell(), textAlign = TextAlign.Center,
node = occupation, text = stringResource(Res.string.character_sheet__skills__special_title),
onClick = { onSkill(occupation) },
onUse = { onUseSkill(occupation) },
) )
characterSheet.specialSKills.forEach { occupation ->
Skill(
modifier = Modifier.cell(),
node = occupation,
onClick = { onSkill(occupation) },
onUse = { onUseSkill(occupation) },
)
}
} }
} }
} }
DecoratedBox( AnimatedVisibility(
modifier = Modifier visible = characterSheet.magicsSkills.isNotEmpty()
.fillMaxWidth()
.padding(vertical = 8.dp),
) { ) {
Column { DecoratedBox(
Text( modifier = Modifier
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp), .fillMaxWidth()
style = MaterialTheme.typography.caption, .padding(vertical = 8.dp),
textAlign = TextAlign.Center, ) {
text = stringResource(Res.string.character_sheet__skills__magic_title), Column {
) Text(
characterSheet.magicsSkills.forEach { magic -> modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp),
Skill( style = MaterialTheme.typography.caption,
modifier = Modifier.cell(), textAlign = TextAlign.Center,
node = magic, text = stringResource(Res.string.character_sheet__skills__magic_title),
onClick = { onSkill(magic) },
onUse = { onUseSkill(magic) },
) )
characterSheet.magicsSkills.forEach { magic ->
Skill(
modifier = Modifier.cell(),
node = magic,
onClick = { onSkill(magic) },
onUse = { onUseSkill(magic) },
)
}
} }
} }
} }

View file

@ -5,6 +5,7 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import com.pixelized.desktop.lwa.business.DamageBonusUseCase import com.pixelized.desktop.lwa.business.DamageBonusUseCase
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase
import com.pixelized.desktop.lwa.repository.characterSheet.SkillDescriptionFactory
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.occupation import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.occupation
@ -57,10 +58,11 @@ import kotlin.math.min
class CharacterSheetEditFactory( class CharacterSheetEditFactory(
private val bonusDamageUseCase: DamageBonusUseCase, private val bonusDamageUseCase: DamageBonusUseCase,
private val skillFactory: SkillFieldFactory, private val skillFieldFactory: SkillFieldFactory,
private val skillDescriptionFactory: SkillDescriptionFactory,
private val normalizer: SkillNormalizerUseCase, private val normalizer: SkillNormalizerUseCase,
) { ) {
fun updateCharacterSheet( suspend fun updateCharacterSheet(
currentSheet: CharacterSheet?, currentSheet: CharacterSheet?,
editedSheet: CharacterSheetEditPageUio, editedSheet: CharacterSheetEditPageUio,
): CharacterSheet { ): CharacterSheet {
@ -121,6 +123,7 @@ class CharacterSheetEditFactory(
CharacterSheet.Skill( CharacterSheet.Skill(
id = editedSkill.id, id = editedSkill.id,
label = editedSkill.label, label = editedSkill.label,
description = skillDescriptionFactory.baseSkillDescription(editedSkill.id),
base = "${editedSkill.base.value}", base = "${editedSkill.base.value}",
bonus = editedSkill.bonus.value.value.toIntOrNull(), bonus = editedSkill.bonus.value.value.toIntOrNull(),
level = editedSkill.level.value.value.toIntOrNull(), level = editedSkill.level.value.value.toIntOrNull(),
@ -135,6 +138,7 @@ class CharacterSheetEditFactory(
CharacterSheet.Skill( CharacterSheet.Skill(
id = editedSkill.id, id = editedSkill.id,
label = editedSkill.label.value.value, label = editedSkill.label.value.value,
description = editedSkill.description.value.value,
base = editedSkill.base.value.value, base = editedSkill.base.value.value,
bonus = editedSkill.bonus.value.value.toIntOrNull(), bonus = editedSkill.bonus.value.value.toIntOrNull(),
level = editedSkill.level.value.value.toIntOrNull(), level = editedSkill.level.value.value.toIntOrNull(),
@ -149,6 +153,7 @@ class CharacterSheetEditFactory(
CharacterSheet.Skill( CharacterSheet.Skill(
id = editedSkill.id, id = editedSkill.id,
label = editedSkill.label.value.value, label = editedSkill.label.value.value,
description = editedSkill.description.value.value,
base = editedSkill.base.value.value, base = editedSkill.base.value.value,
bonus = editedSkill.bonus.value.value.toIntOrNull(), bonus = editedSkill.bonus.value.value.toIntOrNull(),
level = editedSkill.level.value.value.toIntOrNull(), level = editedSkill.level.value.value.toIntOrNull(),
@ -172,49 +177,49 @@ class CharacterSheetEditFactory(
): CharacterSheetEditPageUio { ): CharacterSheetEditPageUio {
val str = SimpleFieldUio( val str = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__characteristics__str), label = getString(Res.string.character_sheet_edit__characteristics__str),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = sheet?.strength?.toString() ?: "", value = sheet?.strength?.toString() ?: "",
placeholder = mutableStateOf("10") placeholder = mutableStateOf("10")
), ),
) )
val dex = SimpleFieldUio( val dex = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__characteristics__dex), label = getString(Res.string.character_sheet_edit__characteristics__dex),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = sheet?.dexterity?.toString() ?: "", value = sheet?.dexterity?.toString() ?: "",
placeholder = mutableStateOf("10"), placeholder = mutableStateOf("10"),
), ),
) )
val con = SimpleFieldUio( val con = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__characteristics__con), label = getString(Res.string.character_sheet_edit__characteristics__con),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = sheet?.constitution?.toString() ?: "", value = sheet?.constitution?.toString() ?: "",
placeholder = mutableStateOf("10"), placeholder = mutableStateOf("10"),
) )
) )
val hei = SimpleFieldUio( val hei = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__characteristics__hei), label = getString(Res.string.character_sheet_edit__characteristics__hei),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = sheet?.height?.toString() ?: "", value = sheet?.height?.toString() ?: "",
placeholder = mutableStateOf("10"), placeholder = mutableStateOf("10"),
) )
) )
val int = SimpleFieldUio( val int = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__characteristics__int), label = getString(Res.string.character_sheet_edit__characteristics__int),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = sheet?.intelligence?.toString() ?: "", value = sheet?.intelligence?.toString() ?: "",
placeholder = mutableStateOf("10"), placeholder = mutableStateOf("10"),
) )
) )
val pow = SimpleFieldUio( val pow = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__characteristics__pow), label = getString(Res.string.character_sheet_edit__characteristics__pow),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = sheet?.power?.toString() ?: "", value = sheet?.power?.toString() ?: "",
placeholder = mutableStateOf("10"), placeholder = mutableStateOf("10"),
) )
) )
val cha = SimpleFieldUio( val cha = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__characteristics__cha), label = getString(Res.string.character_sheet_edit__characteristics__cha),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = sheet?.charisma?.toString() ?: "", value = sheet?.charisma?.toString() ?: "",
placeholder = mutableStateOf("10"), placeholder = mutableStateOf("10"),
) )
@ -233,14 +238,14 @@ class CharacterSheetEditFactory(
val maxHitPoint = SimpleFieldUio( val maxHitPoint = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_hit_point), label = getString(Res.string.character_sheet_edit__sub_characteristics__max_hit_point),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "", value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "",
placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" }, placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" },
) )
) )
val maxPowerPoint = SimpleFieldUio( val maxPowerPoint = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_power_point), label = getString(Res.string.character_sheet_edit__sub_characteristics__max_power_point),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "", value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "",
placeholder = derivedStateOf { "${pow()}" }, placeholder = derivedStateOf { "${pow()}" },
) )
@ -248,7 +253,7 @@ class CharacterSheetEditFactory(
return CharacterSheetEditPageUio( return CharacterSheetEditPageUio(
id = sheet?.id ?: UUID.randomUUID().toString(), id = sheet?.id ?: UUID.randomUUID().toString(),
name = skillFactory.createWrapper( name = skillFieldFactory.createWrapper(
label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)), label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)),
value = sheet?.name ?: "" value = sheet?.name ?: ""
), ),
@ -261,7 +266,7 @@ class CharacterSheetEditFactory(
charisma = cha, charisma = cha,
movement = SimpleFieldUio( movement = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__movement), label = getString(Res.string.character_sheet_edit__sub_characteristics__movement),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = if (sheet?.overrideMovement == true) "${sheet.movement}" else "", value = if (sheet?.overrideMovement == true) "${sheet.movement}" else "",
placeholder = mutableStateOf("10"), placeholder = mutableStateOf("10"),
) )
@ -269,7 +274,7 @@ class CharacterSheetEditFactory(
maxHp = maxHitPoint, maxHp = maxHitPoint,
currentHp = SimpleFieldUio( currentHp = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point), label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
enable = false, enable = false,
placeholder = derivedStateOf { placeholder = derivedStateOf {
val min = min( val min = min(
@ -283,7 +288,7 @@ class CharacterSheetEditFactory(
maxPp = maxPowerPoint, maxPp = maxPowerPoint,
currentPp = SimpleFieldUio( currentPp = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point), label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
enable = false, enable = false,
placeholder = derivedStateOf { placeholder = derivedStateOf {
val min = min( val min = min(
@ -296,7 +301,7 @@ class CharacterSheetEditFactory(
), ),
damageBonus = SimpleFieldUio( damageBonus = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__damage_bonus), label = getString(Res.string.character_sheet_edit__sub_characteristics__damage_bonus),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = if (sheet?.overrideDamageBonus == true) sheet.damageBonus else "", value = if (sheet?.overrideDamageBonus == true) sheet.damageBonus else "",
placeholder = derivedStateOf { placeholder = derivedStateOf {
bonusDamageUseCase.bonusDamage( bonusDamageUseCase.bonusDamage(
@ -308,7 +313,7 @@ class CharacterSheetEditFactory(
), ),
armor = SimpleFieldUio( armor = SimpleFieldUio(
label = getString(Res.string.character_sheet_edit__sub_characteristics__armor), label = getString(Res.string.character_sheet_edit__sub_characteristics__armor),
value = skillFactory.createWrapper( value = skillFieldFactory.createWrapper(
value = if (sheet?.overrideArmor == true) "${sheet.armor}" else "", value = if (sheet?.overrideArmor == true) "${sheet.armor}" else "",
placeholder = mutableStateOf("0"), placeholder = mutableStateOf("0"),
) )
@ -412,9 +417,10 @@ class CharacterSheetEditFactory(
), ),
), ),
specialSkills = sheet?.specialSkills?.map { skill -> specialSkills = sheet?.specialSkills?.map { skill ->
skillFactory.createSkill( skillFieldFactory.createSkill(
id = skill.id, id = skill.id,
label = specialSkillsLabel, label = specialSkillsLabel,
descriptionValue = skill.description ?: "",
labelValue = skill.label, labelValue = skill.label,
baseValue = skill.base, baseValue = skill.base,
bonusValue = skill.bonus?.toString() ?: "", bonusValue = skill.bonus?.toString() ?: "",
@ -422,16 +428,17 @@ class CharacterSheetEditFactory(
options = run { options = run {
val current = sheet.specialSkills.firstOrNull { it.id == skill.id } val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
listOf( listOf(
skillFactory.occupationOption(checked = current?.occupation ?: false), skillFieldFactory.occupationOption(checked = current?.occupation ?: false),
skillFactory.deleteOption { onDeleteSkill(skill.id) }, skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
) )
}, },
) )
} ?: emptyList(), } ?: emptyList(),
magicSkills = sheet?.magicSkills?.map { skill -> magicSkills = sheet?.magicSkills?.map { skill ->
skillFactory.createSkill( skillFieldFactory.createSkill(
id = skill.id, id = skill.id,
label = magicSkillsLabel, label = magicSkillsLabel,
descriptionValue = skill.description ?: "",
labelValue = skill.label, labelValue = skill.label,
baseValue = skill.base, baseValue = skill.base,
bonusValue = skill.bonus?.toString() ?: "", bonusValue = skill.bonus?.toString() ?: "",
@ -439,8 +446,8 @@ class CharacterSheetEditFactory(
options = run { options = run {
val current = sheet.magicSkills.firstOrNull { it.id == skill.id } val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
listOf( listOf(
skillFactory.occupationOption(checked = current?.occupation ?: false), skillFieldFactory.occupationOption(checked = current?.occupation ?: false),
skillFactory.deleteOption { onDeleteSkill(skill.id) }, skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
) )
}, },
) )
@ -448,15 +455,15 @@ class CharacterSheetEditFactory(
actions = sheet?.actions?.map { action -> actions = sheet?.actions?.map { action ->
ActionFieldUio( ActionFieldUio(
id = action.id, id = action.id,
label = skillFactory.createWrapper( label = skillFieldFactory.createWrapper(
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)), label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
value = action.label, value = action.label,
), ),
action = skillFactory.createWrapper( action = skillFieldFactory.createWrapper(
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)), label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
value = action.roll, value = action.roll,
), ),
option = skillFactory.deleteOption { onDeleteSkill(action.id) }, option = skillFieldFactory.deleteOption { onDeleteSkill(action.id) },
) )
} ?: emptyList(), } ?: emptyList(),
) )
@ -474,15 +481,15 @@ class CharacterSheetEditFactory(
id = id, id = id,
label = label, label = label,
base = base, base = base,
bonus = skillFactory.createWrapper( bonus = skillFieldFactory.createWrapper(
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)), label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)),
value = skill?.bonus?.toString() ?: "", value = skill?.bonus?.toString() ?: "",
), ),
level = skillFactory.createWrapper( level = skillFieldFactory.createWrapper(
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)), label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)),
value = skill?.level?.toString() ?: "", value = skill?.level?.toString() ?: "",
), ),
option = skillFactory.occupationOption(skill?.occupation ?: false), option = skillFieldFactory.occupationOption(skill?.occupation ?: false),
) )
} }

View file

@ -273,6 +273,7 @@ fun CharacterSheetEdit(
Column( Column(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
) { ) {
Text( Text(
modifier = Modifier.padding(vertical = 8.dp), modifier = Modifier.padding(vertical = 8.dp),
@ -319,6 +320,7 @@ fun CharacterSheetEdit(
Column( Column(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
) { ) {
Text( Text(
modifier = Modifier.padding(vertical = 8.dp), modifier = Modifier.padding(vertical = 8.dp),

View file

@ -15,6 +15,7 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__de
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__occupation__label import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__occupation__label
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__base_label import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__base_label
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bonus_label import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bonus_label
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__description_label
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__level_label import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__level_label
import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.getString
import java.util.UUID import java.util.UUID
@ -25,6 +26,7 @@ class SkillFieldFactory {
id: String = UUID.randomUUID().toString(), id: String = UUID.randomUUID().toString(),
label: String, label: String,
labelValue: String = "", labelValue: String = "",
descriptionValue: String = "",
baseValue: String = "", baseValue: String = "",
bonusValue: String = "", bonusValue: String = "",
levelValue: String = "", levelValue: String = "",
@ -37,6 +39,10 @@ class SkillFieldFactory {
label = mutableStateOf(label), label = mutableStateOf(label),
value = labelValue, value = labelValue,
), ),
description = createWrapper(
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__description_label)),
value = descriptionValue,
),
base = createWrapper( base = createWrapper(
label = derivedStateOf { label = derivedStateOf {
options options

View file

@ -2,7 +2,9 @@ package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.material.DropdownMenu import androidx.compose.material.DropdownMenu
import androidx.compose.material.Icon import androidx.compose.material.Icon
@ -14,7 +16,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.DropDownMenuItemWrapper import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.DropDownMenuItemWrapper
@ -26,6 +27,7 @@ import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield
class SkillFieldUio( class SkillFieldUio(
val id: String, val id: String,
val label: TextFieldWrapperUio, val label: TextFieldWrapperUio,
val description: TextFieldWrapperUio,
val base: TextFieldWrapperUio, val base: TextFieldWrapperUio,
val bonus: TextFieldWrapperUio, val bonus: TextFieldWrapperUio,
val level: TextFieldWrapperUio, val level: TextFieldWrapperUio,
@ -41,25 +43,38 @@ fun SkillForm(
Row( Row(
modifier = modifier, modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.End), horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
verticalAlignment = Alignment.CenterVertically,
) { ) {
TextFieldWrapper( Column(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
wrapper = field.label, verticalArrangement = Arrangement.spacedBy(space = 4.dp)
) ) {
TextFieldWrapper( Row(
modifier = Modifier.width(width = 96.dp), horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
wrapper = field.base, ) {
) TextFieldWrapper(
TextFieldWrapper( modifier = Modifier.weight(1f),
modifier = Modifier.width(width = 96.dp), wrapper = field.label,
wrapper = field.bonus, )
) TextFieldWrapper(
TextFieldWrapper( modifier = Modifier.width(width = 96.dp),
modifier = Modifier.width(width = 96.dp), wrapper = field.base,
wrapper = field.level, )
) TextFieldWrapper(
modifier = Modifier.width(width = 96.dp),
wrapper = field.bonus,
)
TextFieldWrapper(
modifier = Modifier.width(width = 96.dp),
wrapper = field.level,
)
}
TextFieldWrapper(
modifier = Modifier.fillMaxWidth(),
singleLine = false,
wrapper = field.description,
)
}
if (field.options.isNotEmpty()) { if (field.options.isNotEmpty()) {
Box { Box {
IconButton( IconButton(

View file

@ -15,6 +15,7 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.utils.rememberKeyboardActions import com.pixelized.desktop.lwa.utils.rememberKeyboardActions
import kotlin.math.sin
@Stable @Stable
data class TextFieldWrapperUio( data class TextFieldWrapperUio(
@ -28,13 +29,19 @@ data class TextFieldWrapperUio(
@Composable @Composable
fun TextFieldWrapper( fun TextFieldWrapper(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
singleLine: Boolean = true,
wrapper: TextFieldWrapperUio, wrapper: TextFieldWrapperUio,
) { ) {
val colorScheme = MaterialTheme.colors val colorScheme = MaterialTheme.colors
val focus = LocalFocusManager.current val focus = LocalFocusManager.current
val localModifier = if (singleLine) {
Modifier.height(height = 56.dp)
} else {
Modifier
}
TextField( TextField(
modifier = Modifier.height(height = 56.dp).then(other = modifier), modifier = localModifier.then(other = modifier),
colors = TextFieldDefaults.textFieldColors( colors = TextFieldDefaults.textFieldColors(
backgroundColor = remember(wrapper.enable) { backgroundColor = remember(wrapper.enable) {
when (wrapper.enable) { when (wrapper.enable) {
@ -47,7 +54,7 @@ fun TextFieldWrapper(
focus.moveFocus(FocusDirection.Next) focus.moveFocus(FocusDirection.Next)
}, },
enabled = wrapper.enable, enabled = wrapper.enable,
singleLine = true, singleLine = singleLine,
placeholder = wrapper.placeholder.value?.let { placeholder = wrapper.placeholder.value?.let {
{ {
Text( Text(