Add quality of life (icons, formula instead of plain Ints)
This commit is contained in:
		
							parent
							
								
									8884d047a6
								
							
						
					
					
						commit
						f99a938e64
					
				
					 16 changed files with 235 additions and 145 deletions
				
			
		| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
					<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
    android:width="32dp"
 | 
					    android:width="24dp"
 | 
				
			||||||
    android:height="32dp"
 | 
					    android:height="24dp"
 | 
				
			||||||
    android:viewportWidth="1024"
 | 
					    android:viewportWidth="1024"
 | 
				
			||||||
    android:viewportHeight="1024">
 | 
					    android:viewportHeight="1024">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    android:width="24dp"
 | 
				
			||||||
 | 
					    android:height="24dp"
 | 
				
			||||||
 | 
					    android:viewportWidth="24"
 | 
				
			||||||
 | 
					    android:viewportHeight="24">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <path android:pathData="M0 0h24v24H0z" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					        android:fillColor="#000000"
 | 
				
			||||||
 | 
					        android:pathData="M14 2H6c-1.1 0-1.99 0.9 -1.99 2L4 20c0 1.1 0.89 2 1.99 2H18c1.1 0 2-0.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z" />
 | 
				
			||||||
 | 
					</vector>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    android:width="24dp"
 | 
				
			||||||
 | 
					    android:height="24dp"
 | 
				
			||||||
 | 
					    android:viewportWidth="24"
 | 
				
			||||||
 | 
					    android:viewportHeight="24">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					        android:pathData="M0 0h24v24H0z" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					        android:fillColor="#000000"
 | 
				
			||||||
 | 
					        android:pathData="M20 6h-8l-2-2H4c-1.1 0-1.99 0.9 -1.99 2L2 18c0 1.1 0.9 2 2 2h16c1.1 0 2-0.9 2-2V8c0-1.1-0.9-2-2-2zm0 12H4V8h16v10z" />
 | 
				
			||||||
 | 
					</vector>
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
					<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
    android:width="32dp"
 | 
					    android:width="24dp"
 | 
				
			||||||
    android:height="32dp"
 | 
					    android:height="24dp"
 | 
				
			||||||
    android:viewportWidth="512"
 | 
					    android:viewportWidth="512"
 | 
				
			||||||
    android:viewportHeight="512">
 | 
					    android:viewportHeight="512">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    android:width="24dp"
 | 
				
			||||||
 | 
					    android:height="24dp"
 | 
				
			||||||
 | 
					    android:viewportWidth="24"
 | 
				
			||||||
 | 
					    android:viewportHeight="24">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					        android:fillColor="#000000"
 | 
				
			||||||
 | 
					        android:pathData="M21.96,9.73l-1.43-5C20.41,4.3,20.02,4,19.57,4H4.43C3.98,4,3.59,4.3,3.47,4.73l-1.43,5C1.86,10.36,2.34,11,3,11h2.2L4,20 h2l0.67-5h10.67L18,20h2l-1.2-9H21C21.66,11,22.14,10.36,21.96,9.73z M6.93,13l0.27-2h9.6l0.27,2H6.93z" />
 | 
				
			||||||
 | 
					</vector>
 | 
				
			||||||
| 
						 | 
					@ -14,45 +14,31 @@ class SkillValueComputationUseCase(
 | 
				
			||||||
        skill: CharacterSheet.Skill,
 | 
					        skill: CharacterSheet.Skill,
 | 
				
			||||||
        diminished: Int,
 | 
					        diminished: Int,
 | 
				
			||||||
    ): Int {
 | 
					    ): Int {
 | 
				
			||||||
        val baseSum = arithmeticParser.parse(skill.base).sumOf { instruction ->
 | 
					        val base: Int = arithmeticParser.parse(skill.base).compute(sheet = sheet).let {
 | 
				
			||||||
            when (instruction) {
 | 
					            when (skill.occupation) {
 | 
				
			||||||
                is Instruction.Dice -> 0
 | 
					                true -> max(MIN_OCCUPATION_VALUE, it)
 | 
				
			||||||
 | 
					                else -> it
 | 
				
			||||||
                is Instruction.Flat -> {
 | 
					            }
 | 
				
			||||||
                    instruction.value
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                is Instruction.Word -> {
 | 
					 | 
				
			||||||
                    when (instruction.type) {
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.BDC -> 0
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.BDD -> 0
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.STR -> sheet.strength
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.DEX -> sheet.dexterity
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.CON -> sheet.constitution
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.HEI -> sheet.height
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.INT -> sheet.intelligence
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.POW -> sheet.power
 | 
					 | 
				
			||||||
                        Instruction.Word.Type.CHA -> sheet.charisma
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } * instruction.sign
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        val bonus = skill.bonus?.let(arithmeticParser::parse)?.compute(sheet = sheet) ?: 0
 | 
				
			||||||
 | 
					        val level = skill.level?.let(arithmeticParser::parse)?.compute(sheet = sheet) ?: 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val base = if (skill.occupation) {
 | 
					        return max(base + bonus + level - diminished, 0)
 | 
				
			||||||
            max(MIN_OCCUPATION_VALUE, baseSum)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            baseSum
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return max(base + (skill.bonus ?: 0) + (skill.level ?: 0) - diminished, 0)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun computeRoll(
 | 
					    fun computeRoll(
 | 
				
			||||||
        sheet: CharacterSheet,
 | 
					        sheet: CharacterSheet,
 | 
				
			||||||
        roll: String,
 | 
					        roll: String,
 | 
				
			||||||
    ): Int { // TODO Roll detail instead of an simple Int.
 | 
					    ): Int {
 | 
				
			||||||
 | 
					        return arithmeticParser.parse(value = roll).compute(sheet = sheet)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO return RollDetail instance instead of an simple Int.
 | 
				
			||||||
 | 
					    private fun List<Instruction>.compute(
 | 
				
			||||||
 | 
					        sheet: CharacterSheet,
 | 
				
			||||||
 | 
					    ): Int {
 | 
				
			||||||
        print("Roll ->")
 | 
					        print("Roll ->")
 | 
				
			||||||
        return arithmeticParser.parse(roll).sumOf { instruction ->
 | 
					        return sumOf { instruction ->
 | 
				
			||||||
            print(" ($instruction):")
 | 
					            print(" ($instruction):")
 | 
				
			||||||
            val value = when (instruction) {
 | 
					            val value = when (instruction) {
 | 
				
			||||||
                is Instruction.Dice -> rollUseCase.roll(dice = instruction)
 | 
					                is Instruction.Dice -> rollUseCase.roll(dice = instruction)
 | 
				
			||||||
| 
						 | 
					@ -99,7 +85,9 @@ class SkillValueComputationUseCase(
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            (value * instruction.sign).also { print("$it") }
 | 
					            (value * instruction.sign).also { print("$it") }
 | 
				
			||||||
        }.also { println() }
 | 
					        }.also {
 | 
				
			||||||
 | 
					            println()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    companion object {
 | 
					    companion object {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,8 +36,8 @@ data class CharacterSheet(
 | 
				
			||||||
        val label: String,
 | 
					        val label: String,
 | 
				
			||||||
        val description: String?,
 | 
					        val description: String?,
 | 
				
			||||||
        val base: String,
 | 
					        val base: String,
 | 
				
			||||||
        val bonus: Int?,
 | 
					        val bonus: String?,
 | 
				
			||||||
        val level: Int?,
 | 
					        val level: String?,
 | 
				
			||||||
        val occupation: Boolean,
 | 
					        val occupation: Boolean,
 | 
				
			||||||
        val used: Boolean,
 | 
					        val used: Boolean,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
| 
						 | 
					@ -66,4 +66,19 @@ data class CharacterSheet(
 | 
				
			||||||
        const val SLEIGHT_OF_HAND_ID = "SLEIGHT_OF_HAND"
 | 
					        const val SLEIGHT_OF_HAND_ID = "SLEIGHT_OF_HAND"
 | 
				
			||||||
        const val AID_ID = "AID"
 | 
					        const val AID_ID = "AID"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object CharacteristicId {
 | 
				
			||||||
 | 
					        const val STR = "STR"
 | 
				
			||||||
 | 
					        const val DEX = "DEX"
 | 
				
			||||||
 | 
					        const val CON = "CON"
 | 
				
			||||||
 | 
					        const val HEI = "HEI"
 | 
				
			||||||
 | 
					        const val INT = "INT"
 | 
				
			||||||
 | 
					        const val POW = "POW"
 | 
				
			||||||
 | 
					        const val CHA = "CHA"
 | 
				
			||||||
 | 
					        const val MOV = "MOV"
 | 
				
			||||||
 | 
					        const val HP = "HP"
 | 
				
			||||||
 | 
					        const val PP = "PP"
 | 
				
			||||||
 | 
					        const val DMG = "DMG"
 | 
				
			||||||
 | 
					        const val ARMOR = "ARMOR"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -38,8 +38,8 @@ data class CharacterSheetJsonV1(
 | 
				
			||||||
        val label: String,
 | 
					        val label: String,
 | 
				
			||||||
        val description: String?,
 | 
					        val description: String?,
 | 
				
			||||||
        val base: String,
 | 
					        val base: String,
 | 
				
			||||||
        val bonus: Int?,
 | 
					        val bonus: String?,
 | 
				
			||||||
        val level: Int?,
 | 
					        val level: String?,
 | 
				
			||||||
        val occupation: Boolean,
 | 
					        val occupation: Boolean,
 | 
				
			||||||
        val used: Boolean,
 | 
					        val used: Boolean,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ 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.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.CharacteristicId
 | 
				
			||||||
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
 | 
				
			||||||
| 
						 | 
					@ -37,21 +38,19 @@ class CharacterSheetFactory(
 | 
				
			||||||
    private val skillUseCase: SkillValueComputationUseCase,
 | 
					    private val skillUseCase: SkillValueComputationUseCase,
 | 
				
			||||||
    private val skillDescriptionFactory: SkillDescriptionFactory,
 | 
					    private val skillDescriptionFactory: SkillDescriptionFactory,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    companion object {
 | 
					 | 
				
			||||||
        const val HP = "HP"
 | 
					 | 
				
			||||||
        const val PP = "PP"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    suspend fun convertToUio(
 | 
					    suspend fun convertToUio(
 | 
				
			||||||
        sheet: CharacterSheet,
 | 
					        sheet: CharacterSheet?,
 | 
				
			||||||
        diminished: Int,
 | 
					        diminished: Int,
 | 
				
			||||||
    ): CharacterSheetPageUio {
 | 
					    ): CharacterSheetPageUio? {
 | 
				
			||||||
 | 
					        if (sheet == null) return null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return CharacterSheetPageUio(
 | 
					        return CharacterSheetPageUio(
 | 
				
			||||||
            id = sheet.id,
 | 
					            id = sheet.id,
 | 
				
			||||||
            name = sheet.name,
 | 
					            name = sheet.name,
 | 
				
			||||||
            characteristics = listOf(
 | 
					            characteristics = listOf(
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "STR",
 | 
					                    id = CharacteristicId.STR,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__str),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__str),
 | 
				
			||||||
                    value = "${sheet.strength}",
 | 
					                    value = "${sheet.strength}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -61,7 +60,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "DEX",
 | 
					                    id = CharacteristicId.DEX,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__dex),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__dex),
 | 
				
			||||||
                    value = "${sheet.dexterity}",
 | 
					                    value = "${sheet.dexterity}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -71,7 +70,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "CON",
 | 
					                    id = CharacteristicId.CON,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__con),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__con),
 | 
				
			||||||
                    value = "${sheet.constitution}",
 | 
					                    value = "${sheet.constitution}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -81,7 +80,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "HEI",
 | 
					                    id = CharacteristicId.HEI,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__hei),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__hei),
 | 
				
			||||||
                    value = "${sheet.height}",
 | 
					                    value = "${sheet.height}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -91,7 +90,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "INT",
 | 
					                    id = CharacteristicId.INT,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__int),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__int),
 | 
				
			||||||
                    value = "${sheet.intelligence}",
 | 
					                    value = "${sheet.intelligence}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -101,7 +100,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "POW",
 | 
					                    id = CharacteristicId.POW,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__pow),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__pow),
 | 
				
			||||||
                    value = "${sheet.power}",
 | 
					                    value = "${sheet.power}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -111,7 +110,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "CHA",
 | 
					                    id = CharacteristicId.CHA,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__cha),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__cha),
 | 
				
			||||||
                    value = "${sheet.charisma}",
 | 
					                    value = "${sheet.charisma}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -123,7 +122,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            subCharacteristics = listOf(
 | 
					            subCharacteristics = listOf(
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "MOV",
 | 
					                    id = CharacteristicId.MOV,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__movement),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__movement),
 | 
				
			||||||
                    value = "${sheet.movement}",
 | 
					                    value = "${sheet.movement}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -133,7 +132,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = HP,
 | 
					                    id = CharacteristicId.HP,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__hit_point),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__hit_point),
 | 
				
			||||||
                    value = "${sheet.currentHp}/${sheet.maxHp}",
 | 
					                    value = "${sheet.currentHp}/${sheet.maxHp}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -143,7 +142,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = true,
 | 
					                    editable = true,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = PP,
 | 
					                    id = CharacteristicId.PP,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__power_point),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__power_point),
 | 
				
			||||||
                    value = "${sheet.currentPp}/${sheet.maxPp}",
 | 
					                    value = "${sheet.currentPp}/${sheet.maxPp}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -153,7 +152,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = true,
 | 
					                    editable = true,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "DMG",
 | 
					                    id = CharacteristicId.DMG,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
 | 
				
			||||||
                    value = sheet.damageBonus,
 | 
					                    value = sheet.damageBonus,
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					@ -163,7 +162,7 @@ class CharacterSheetFactory(
 | 
				
			||||||
                    editable = false,
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
                    id = "ARMOR",
 | 
					                    id = CharacteristicId.ARMOR,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__armor),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__armor),
 | 
				
			||||||
                    value = "${sheet.armor}",
 | 
					                    value = "${sheet.armor}",
 | 
				
			||||||
                    tooltips = TooltipUio(
 | 
					                    tooltips = TooltipUio(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,8 +77,8 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet__skills_
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__special_title
 | 
					import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__special_title
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__title
 | 
					import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__title
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__edit__title
 | 
					import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__edit__title
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp
 | 
					import lwacharactersheet.composeapp.generated.resources.ic_d20_24dp
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.ic_skull_32dp
 | 
					import lwacharactersheet.composeapp.generated.resources.ic_skull_24dp
 | 
				
			||||||
import org.jetbrains.compose.resources.getString
 | 
					import org.jetbrains.compose.resources.getString
 | 
				
			||||||
import org.jetbrains.compose.resources.painterResource
 | 
					import org.jetbrains.compose.resources.painterResource
 | 
				
			||||||
import org.jetbrains.compose.resources.stringResource
 | 
					import org.jetbrains.compose.resources.stringResource
 | 
				
			||||||
| 
						 | 
					@ -295,7 +295,7 @@ fun CharacterSheetPageContent(
 | 
				
			||||||
                        ) {
 | 
					                        ) {
 | 
				
			||||||
                            Icon(
 | 
					                            Icon(
 | 
				
			||||||
                                modifier = Modifier.size(size = 24.dp),
 | 
					                                modifier = Modifier.size(size = 24.dp),
 | 
				
			||||||
                                painter = painterResource(Res.drawable.ic_skull_32dp),
 | 
					                                painter = painterResource(Res.drawable.ic_skull_24dp),
 | 
				
			||||||
                                tint = MaterialTheme.colors.primary,
 | 
					                                tint = MaterialTheme.colors.primary,
 | 
				
			||||||
                                contentDescription = null,
 | 
					                                contentDescription = null,
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
| 
						 | 
					@ -657,7 +657,7 @@ private fun Roll(
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        Icon(
 | 
					        Icon(
 | 
				
			||||||
            modifier = Modifier.size(size = 24.dp),
 | 
					            modifier = Modifier.size(size = 24.dp),
 | 
				
			||||||
            painter = painterResource(Res.drawable.ic_d20_32dp),
 | 
					            painter = painterResource(Res.drawable.ic_d20_24dp),
 | 
				
			||||||
            tint = MaterialTheme.colors.primary,
 | 
					            tint = MaterialTheme.colors.primary,
 | 
				
			||||||
            contentDescription = null,
 | 
					            contentDescription = null,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
package com.pixelized.desktop.lwa.screen.characterSheet.detail
 | 
					package com.pixelized.desktop.lwa.screen.characterSheet.detail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.compose.runtime.Composable
 | 
					import androidx.compose.runtime.Composable
 | 
				
			||||||
import androidx.compose.runtime.Stable
 | 
					 | 
				
			||||||
import androidx.compose.runtime.State
 | 
					import androidx.compose.runtime.State
 | 
				
			||||||
 | 
					import androidx.compose.runtime.collectAsState
 | 
				
			||||||
import androidx.compose.runtime.mutableStateOf
 | 
					import androidx.compose.runtime.mutableStateOf
 | 
				
			||||||
import androidx.compose.ui.text.TextRange
 | 
					import androidx.compose.ui.text.TextRange
 | 
				
			||||||
import androidx.compose.ui.text.input.TextFieldValue
 | 
					import androidx.compose.ui.text.input.TextFieldValue
 | 
				
			||||||
| 
						 | 
					@ -11,14 +11,12 @@ import androidx.lifecycle.ViewModel
 | 
				
			||||||
import androidx.lifecycle.viewModelScope
 | 
					import androidx.lifecycle.viewModelScope
 | 
				
			||||||
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetDestination
 | 
					import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetDestination
 | 
				
			||||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
 | 
					import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
 | 
				
			||||||
 | 
					import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
 | 
				
			||||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio
 | 
				
			||||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialogUio
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialogUio
 | 
				
			||||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.StatChangeDialogUio
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.StatChangeDialogUio
 | 
				
			||||||
import com.pixelized.desktop.lwa.utils.extention.collectAsState
 | 
					import com.pixelized.desktop.lwa.utils.extention.collectAsState
 | 
				
			||||||
import kotlinx.coroutines.flow.SharingStarted
 | 
					 | 
				
			||||||
import kotlinx.coroutines.flow.combine
 | 
					import kotlinx.coroutines.flow.combine
 | 
				
			||||||
import kotlinx.coroutines.flow.stateIn
 | 
					 | 
				
			||||||
import kotlinx.coroutines.runBlocking
 | 
					 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
					import lwacharactersheet.composeapp.generated.resources.Res
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__diminished__label
 | 
					import lwacharactersheet.composeapp.generated.resources.character_sheet__diminished__label
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
 | 
					import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
 | 
				
			||||||
| 
						 | 
					@ -49,33 +47,26 @@ class CharacterSheetViewModel(
 | 
				
			||||||
    private val _diminishedDialog = mutableStateOf<DiminishedStatDialogUio?>(null)
 | 
					    private val _diminishedDialog = mutableStateOf<DiminishedStatDialogUio?>(null)
 | 
				
			||||||
    val diminishedDialog: State<DiminishedStatDialogUio?> get() = _diminishedDialog
 | 
					    val diminishedDialog: State<DiminishedStatDialogUio?> get() = _diminishedDialog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val diminishedValueFlow = repository.characterDiminishedFlow(id = argument.id)
 | 
				
			||||||
    val diminishedValue: State<Int?>
 | 
					    val diminishedValue: State<Int?>
 | 
				
			||||||
        @Composable
 | 
					        @Composable
 | 
				
			||||||
        @Stable
 | 
					        get() = diminishedValueFlow.collectAsState { it ->
 | 
				
			||||||
        get() = repository
 | 
					            it.takeIf { it > 0 }
 | 
				
			||||||
            .characterDiminishedFlow(id = argument.id)
 | 
					        }
 | 
				
			||||||
            .collectAsState { it -> it.takeIf { it > 0 } }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val sheetFlow = combine(
 | 
				
			||||||
 | 
					        repository.characterSheetFlow(id = argument.id),
 | 
				
			||||||
 | 
					        repository.characterDiminishedFlow(id = argument.id),
 | 
				
			||||||
 | 
					        transform = { sheet, diminished ->
 | 
				
			||||||
 | 
					            factory.convertToUio(sheet = sheet, diminished = diminished)
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    val sheet: State<CharacterSheetPageUio?>
 | 
					    val sheet: State<CharacterSheetPageUio?>
 | 
				
			||||||
        @Composable
 | 
					        @Composable
 | 
				
			||||||
        @Stable
 | 
					        get() = sheetFlow.collectAsState(
 | 
				
			||||||
        get() = combine(
 | 
					            initial = null,
 | 
				
			||||||
            repository.characterSheetFlow(id = argument.id),
 | 
					            context = viewModelScope.coroutineContext,
 | 
				
			||||||
            repository.characterDiminishedFlow(id = argument.id),
 | 
					        )
 | 
				
			||||||
            transform = { sheet, diminished -> sheet to diminished },
 | 
					 | 
				
			||||||
        ).stateIn(
 | 
					 | 
				
			||||||
            scope = viewModelScope,
 | 
					 | 
				
			||||||
            started = SharingStarted.Lazily,
 | 
					 | 
				
			||||||
            initialValue = run {
 | 
					 | 
				
			||||||
                val sheet = repository.characterSheetFlow(id = argument.id).value
 | 
					 | 
				
			||||||
                val diminished = repository.characterDiminishedFlow(id = argument.id).value
 | 
					 | 
				
			||||||
                sheet to diminished
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        ).collectAsState { (sheet, diminished) ->
 | 
					 | 
				
			||||||
            sheet?.let { model ->
 | 
					 | 
				
			||||||
                runBlocking { factory.convertToUio(sheet = model, diminished = diminished) }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun deleteCharacter(id: String) {
 | 
					    fun deleteCharacter(id: String) {
 | 
				
			||||||
        repository.delete(id = id)
 | 
					        repository.delete(id = id)
 | 
				
			||||||
| 
						 | 
					@ -120,14 +111,14 @@ class CharacterSheetViewModel(
 | 
				
			||||||
    suspend fun showSubCharacteristicDialog(id: String) {
 | 
					    suspend fun showSubCharacteristicDialog(id: String) {
 | 
				
			||||||
        repository.characterSheetFlow(id = argument.id).value?.let { sheet ->
 | 
					        repository.characterSheetFlow(id = argument.id).value?.let { sheet ->
 | 
				
			||||||
            _statChangeDialog.value = when (id) {
 | 
					            _statChangeDialog.value = when (id) {
 | 
				
			||||||
                CharacterSheetFactory.HP -> {
 | 
					                CharacterSheet.CharacteristicId.HP -> {
 | 
				
			||||||
                    val value = mutableStateOf(
 | 
					                    val value = mutableStateOf(
 | 
				
			||||||
                        "${sheet.currentHp}".let {
 | 
					                        "${sheet.currentHp}".let {
 | 
				
			||||||
                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
					                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    StatChangeDialogUio(
 | 
					                    StatChangeDialogUio(
 | 
				
			||||||
                        id = CharacterSheetFactory.HP,
 | 
					                        id = CharacterSheet.CharacteristicId.HP,
 | 
				
			||||||
                        label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__hit_point),
 | 
					                        label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__hit_point),
 | 
				
			||||||
                        value = { value.value },
 | 
					                        value = { value.value },
 | 
				
			||||||
                        onValueChange = { value.value = it },
 | 
					                        onValueChange = { value.value = it },
 | 
				
			||||||
| 
						 | 
					@ -135,14 +126,14 @@ class CharacterSheetViewModel(
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                CharacterSheetFactory.PP -> {
 | 
					                CharacterSheet.CharacteristicId.PP -> {
 | 
				
			||||||
                    val value = mutableStateOf(
 | 
					                    val value = mutableStateOf(
 | 
				
			||||||
                        "${sheet.currentPp}".let {
 | 
					                        "${sheet.currentPp}".let {
 | 
				
			||||||
                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
					                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    StatChangeDialogUio(
 | 
					                    StatChangeDialogUio(
 | 
				
			||||||
                        id = CharacterSheetFactory.PP,
 | 
					                        id = CharacterSheet.CharacteristicId.PP,
 | 
				
			||||||
                        label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__power_point),
 | 
					                        label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__power_point),
 | 
				
			||||||
                        value = { value.value },
 | 
					                        value = { value.value },
 | 
				
			||||||
                        onValueChange = { value.value = it },
 | 
					                        onValueChange = { value.value = it },
 | 
				
			||||||
| 
						 | 
					@ -165,8 +156,20 @@ class CharacterSheetViewModel(
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        val sheet = repository.characterSheetFlow(id = argument.id).value
 | 
					        val sheet = repository.characterSheetFlow(id = argument.id).value
 | 
				
			||||||
        val updated = when (characteristicId) {
 | 
					        val updated = when (characteristicId) {
 | 
				
			||||||
            CharacterSheetFactory.HP -> sheet?.copy(currentHp = max(0, min(sheet.maxHp, value)))
 | 
					            CharacterSheet.CharacteristicId.HP -> sheet?.copy(
 | 
				
			||||||
            CharacterSheetFactory.PP -> sheet?.copy(currentPp = max(0, min(sheet.maxPp, value)))
 | 
					                currentHp = max(
 | 
				
			||||||
 | 
					                    0,
 | 
				
			||||||
 | 
					                    min(sheet.maxHp, value)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CharacterSheet.CharacteristicId.PP -> sheet?.copy(
 | 
				
			||||||
 | 
					                currentPp = max(
 | 
				
			||||||
 | 
					                    0,
 | 
				
			||||||
 | 
					                    min(sheet.maxPp, value)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            else -> null
 | 
					            else -> null
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        updated?.let {
 | 
					        updated?.let {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,8 +125,8 @@ class CharacterSheetEditFactory(
 | 
				
			||||||
                    label = editedSkill.label,
 | 
					                    label = editedSkill.label,
 | 
				
			||||||
                    description = skillDescriptionFactory.baseSkillDescription(editedSkill.id),
 | 
					                    description = skillDescriptionFactory.baseSkillDescription(editedSkill.id),
 | 
				
			||||||
                    base = "${editedSkill.base.value}",
 | 
					                    base = "${editedSkill.base.value}",
 | 
				
			||||||
                    bonus = editedSkill.bonus.value.value.toIntOrNull(),
 | 
					                    bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() },
 | 
				
			||||||
                    level = editedSkill.level.value.value.toIntOrNull(),
 | 
					                    level = editedSkill.level.value.value.takeIf { it.isNotBlank() },
 | 
				
			||||||
                    occupation = editedSkill.option.checked.value,
 | 
					                    occupation = editedSkill.option.checked.value,
 | 
				
			||||||
                    used = currentSkill?.used ?: false,
 | 
					                    used = currentSkill?.used ?: false,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
| 
						 | 
					@ -140,8 +140,8 @@ class CharacterSheetEditFactory(
 | 
				
			||||||
                    label = editedSkill.label.value.value,
 | 
					                    label = editedSkill.label.value.value,
 | 
				
			||||||
                    description = editedSkill.description.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.takeIf { it.isNotBlank() },
 | 
				
			||||||
                    level = editedSkill.level.value.value.toIntOrNull(),
 | 
					                    level = editedSkill.level.value.value.takeIf { it.isNotBlank() },
 | 
				
			||||||
                    occupation = editedSkill.options.occupation,
 | 
					                    occupation = editedSkill.options.occupation,
 | 
				
			||||||
                    used = currentSkill?.used ?: false,
 | 
					                    used = currentSkill?.used ?: false,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
| 
						 | 
					@ -155,8 +155,8 @@ class CharacterSheetEditFactory(
 | 
				
			||||||
                    label = editedSkill.label.value.value,
 | 
					                    label = editedSkill.label.value.value,
 | 
				
			||||||
                    description = editedSkill.description.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.takeIf { it.isNotBlank() },
 | 
				
			||||||
                    level = editedSkill.level.value.value.toIntOrNull(),
 | 
					                    level = editedSkill.level.value.value.takeIf { it.isNotBlank() },
 | 
				
			||||||
                    occupation = editedSkill.options.occupation,
 | 
					                    occupation = editedSkill.options.occupation,
 | 
				
			||||||
                    used = currentSkill?.used ?: false,
 | 
					                    used = currentSkill?.used ?: false,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
| 
						 | 
					@ -423,8 +423,8 @@ class CharacterSheetEditFactory(
 | 
				
			||||||
                    descriptionValue = skill.description ?: "",
 | 
					                    descriptionValue = skill.description ?: "",
 | 
				
			||||||
                    labelValue = skill.label,
 | 
					                    labelValue = skill.label,
 | 
				
			||||||
                    baseValue = skill.base,
 | 
					                    baseValue = skill.base,
 | 
				
			||||||
                    bonusValue = skill.bonus?.toString() ?: "",
 | 
					                    bonusValue = skill.bonus ?: "",
 | 
				
			||||||
                    levelValue = skill.level?.toString() ?: "",
 | 
					                    levelValue = skill.level ?: "",
 | 
				
			||||||
                    options = run {
 | 
					                    options = run {
 | 
				
			||||||
                        val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
 | 
					                        val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
 | 
				
			||||||
                        listOf(
 | 
					                        listOf(
 | 
				
			||||||
| 
						 | 
					@ -441,12 +441,14 @@ class CharacterSheetEditFactory(
 | 
				
			||||||
                    descriptionValue = skill.description ?: "",
 | 
					                    descriptionValue = skill.description ?: "",
 | 
				
			||||||
                    labelValue = skill.label,
 | 
					                    labelValue = skill.label,
 | 
				
			||||||
                    baseValue = skill.base,
 | 
					                    baseValue = skill.base,
 | 
				
			||||||
                    bonusValue = skill.bonus?.toString() ?: "",
 | 
					                    bonusValue = skill.bonus ?: "",
 | 
				
			||||||
                    levelValue = skill.level?.toString() ?: "",
 | 
					                    levelValue = skill.level ?: "",
 | 
				
			||||||
                    options = run {
 | 
					                    options = run {
 | 
				
			||||||
                        val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
 | 
					                        val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
 | 
				
			||||||
                        listOf(
 | 
					                        listOf(
 | 
				
			||||||
                            skillFieldFactory.occupationOption(checked = current?.occupation ?: false),
 | 
					                            skillFieldFactory.occupationOption(
 | 
				
			||||||
 | 
					                                checked = current?.occupation ?: false
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
                            skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
 | 
					                            skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
| 
						 | 
					@ -483,11 +485,11 @@ class CharacterSheetEditFactory(
 | 
				
			||||||
            base = base,
 | 
					            base = base,
 | 
				
			||||||
            bonus = skillFieldFactory.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 ?: "",
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            level = skillFieldFactory.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 ?: "",
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            option = skillFieldFactory.occupationOption(skill?.occupation ?: false),
 | 
					            option = skillFieldFactory.occupationOption(skill?.occupation ?: false),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,11 +3,15 @@ package com.pixelized.desktop.lwa.screen.main
 | 
				
			||||||
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.Column
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.Row
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.Spacer
 | 
				
			||||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
					import androidx.compose.foundation.layout.fillMaxSize
 | 
				
			||||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
					import androidx.compose.foundation.layout.fillMaxWidth
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.height
 | 
				
			||||||
import androidx.compose.foundation.layout.padding
 | 
					import androidx.compose.foundation.layout.padding
 | 
				
			||||||
import androidx.compose.foundation.rememberScrollState
 | 
					import androidx.compose.foundation.rememberScrollState
 | 
				
			||||||
import androidx.compose.foundation.verticalScroll
 | 
					import androidx.compose.foundation.verticalScroll
 | 
				
			||||||
 | 
					import androidx.compose.material.Icon
 | 
				
			||||||
import androidx.compose.material.Surface
 | 
					import androidx.compose.material.Surface
 | 
				
			||||||
import androidx.compose.material.Text
 | 
					import androidx.compose.material.Text
 | 
				
			||||||
import androidx.compose.material.TextButton
 | 
					import androidx.compose.material.TextButton
 | 
				
			||||||
| 
						 | 
					@ -28,11 +32,16 @@ import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetWin
 | 
				
			||||||
import kotlinx.coroutines.runBlocking
 | 
					import kotlinx.coroutines.runBlocking
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
					import lwacharactersheet.composeapp.generated.resources.Res
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__create__title
 | 
					import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__create__title
 | 
				
			||||||
 | 
					import lwacharactersheet.composeapp.generated.resources.ic_d20_24dp
 | 
				
			||||||
 | 
					import lwacharactersheet.composeapp.generated.resources.ic_file_24dp
 | 
				
			||||||
 | 
					import lwacharactersheet.composeapp.generated.resources.ic_folder_24dp
 | 
				
			||||||
 | 
					import lwacharactersheet.composeapp.generated.resources.ic_table_24dp
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.main_page__create_action
 | 
					import lwacharactersheet.composeapp.generated.resources.main_page__create_action
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.main_page__network_action
 | 
					import lwacharactersheet.composeapp.generated.resources.main_page__network_action
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.main_page__open_save_directory
 | 
					import lwacharactersheet.composeapp.generated.resources.main_page__open_save_directory
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.main_page__roll_history_action
 | 
					import lwacharactersheet.composeapp.generated.resources.main_page__roll_history_action
 | 
				
			||||||
import org.jetbrains.compose.resources.getString
 | 
					import org.jetbrains.compose.resources.getString
 | 
				
			||||||
 | 
					import org.jetbrains.compose.resources.painterResource
 | 
				
			||||||
import org.jetbrains.compose.resources.stringResource
 | 
					import org.jetbrains.compose.resources.stringResource
 | 
				
			||||||
import org.koin.compose.viewmodel.koinViewModel
 | 
					import org.koin.compose.viewmodel.koinViewModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,65 +112,100 @@ fun MainPageContent(
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    Column(
 | 
					    Column(
 | 
				
			||||||
        modifier = modifier,
 | 
					        modifier = modifier,
 | 
				
			||||||
        verticalArrangement = Arrangement.spacedBy(16.dp),
 | 
					        verticalArrangement = Arrangement.spacedBy(4.dp),
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        Column {
 | 
					        characters.value.forEach { sheet ->
 | 
				
			||||||
            characters.value.forEach { sheet ->
 | 
					            TextButton(
 | 
				
			||||||
                TextButton(
 | 
					                onClick = { onCharacter(sheet) },
 | 
				
			||||||
                    onClick = { onCharacter(sheet) },
 | 
					            ) {
 | 
				
			||||||
                ) {
 | 
					                Text(
 | 
				
			||||||
                    Text(
 | 
					                    modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
                        modifier = Modifier.fillMaxWidth(),
 | 
					                    overflow = TextOverflow.Ellipsis,
 | 
				
			||||||
                        overflow = TextOverflow.Ellipsis,
 | 
					                    textAlign = TextAlign.Start,
 | 
				
			||||||
                        textAlign = TextAlign.Start,
 | 
					                    maxLines = 1,
 | 
				
			||||||
                        maxLines = 1,
 | 
					                    text = sheet.name,
 | 
				
			||||||
                        text = sheet.name,
 | 
					                )
 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Spacer(modifier = Modifier.height(height = 24.dp))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TextButton(
 | 
					        TextButton(
 | 
				
			||||||
            onClick = onCreateCharacter,
 | 
					            onClick = onCreateCharacter,
 | 
				
			||||||
        ) {
 | 
					        ) {
 | 
				
			||||||
            Text(
 | 
					            Row(
 | 
				
			||||||
                modifier = Modifier.fillMaxWidth(),
 | 
					                modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
                maxLines = 1,
 | 
					                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
				
			||||||
                overflow = TextOverflow.Ellipsis,
 | 
					                verticalAlignment = Alignment.CenterVertically,
 | 
				
			||||||
                textAlign = TextAlign.Start,
 | 
					            ) {
 | 
				
			||||||
                text = stringResource(Res.string.main_page__create_action),
 | 
					                Icon(
 | 
				
			||||||
            )
 | 
					                    painter = painterResource(Res.drawable.ic_file_24dp),
 | 
				
			||||||
 | 
					                    contentDescription = null,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                Text(
 | 
				
			||||||
 | 
					                    maxLines = 1,
 | 
				
			||||||
 | 
					                    overflow = TextOverflow.Ellipsis,
 | 
				
			||||||
 | 
					                    textAlign = TextAlign.Start,
 | 
				
			||||||
 | 
					                    text = stringResource(Res.string.main_page__create_action),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TextButton(
 | 
					        TextButton(
 | 
				
			||||||
            onClick = onOpenSaveDirectory,
 | 
					            onClick = onOpenSaveDirectory,
 | 
				
			||||||
        ) {
 | 
					        ) {
 | 
				
			||||||
            Text(
 | 
					            Row(
 | 
				
			||||||
                modifier = Modifier.fillMaxWidth(),
 | 
					                modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
                maxLines = 1,
 | 
					                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
				
			||||||
                overflow = TextOverflow.Ellipsis,
 | 
					                verticalAlignment = Alignment.CenterVertically,
 | 
				
			||||||
                textAlign = TextAlign.Start,
 | 
					            ) {
 | 
				
			||||||
                text = stringResource(Res.string.main_page__open_save_directory),
 | 
					                Icon(
 | 
				
			||||||
            )
 | 
					                    painter = painterResource(Res.drawable.ic_folder_24dp),
 | 
				
			||||||
 | 
					                    contentDescription = null,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                Text(
 | 
				
			||||||
 | 
					                    maxLines = 1,
 | 
				
			||||||
 | 
					                    overflow = TextOverflow.Ellipsis,
 | 
				
			||||||
 | 
					                    textAlign = TextAlign.Start,
 | 
				
			||||||
 | 
					                    text = stringResource(Res.string.main_page__open_save_directory),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Column {
 | 
					        TextButton(
 | 
				
			||||||
            TextButton(
 | 
					            onClick = onRollHistory,
 | 
				
			||||||
                onClick = onRollHistory,
 | 
					        ) {
 | 
				
			||||||
 | 
					            Row(
 | 
				
			||||||
 | 
					                modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
 | 
					                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
				
			||||||
 | 
					                verticalAlignment = Alignment.CenterVertically,
 | 
				
			||||||
            ) {
 | 
					            ) {
 | 
				
			||||||
 | 
					                Icon(
 | 
				
			||||||
 | 
					                    painter = painterResource(Res.drawable.ic_d20_24dp),
 | 
				
			||||||
 | 
					                    contentDescription = null,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                Text(
 | 
					                Text(
 | 
				
			||||||
                    modifier = Modifier.fillMaxWidth(),
 | 
					 | 
				
			||||||
                    maxLines = 1,
 | 
					                    maxLines = 1,
 | 
				
			||||||
                    overflow = TextOverflow.Ellipsis,
 | 
					                    overflow = TextOverflow.Ellipsis,
 | 
				
			||||||
                    textAlign = TextAlign.Start,
 | 
					                    textAlign = TextAlign.Start,
 | 
				
			||||||
                    text = stringResource(Res.string.main_page__roll_history_action),
 | 
					                    text = stringResource(Res.string.main_page__roll_history_action),
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TextButton(
 | 
					        }
 | 
				
			||||||
                onClick = onNetwork,
 | 
					
 | 
				
			||||||
 | 
					        TextButton(
 | 
				
			||||||
 | 
					            onClick = onNetwork,
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            Row(
 | 
				
			||||||
 | 
					                modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
 | 
					                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
				
			||||||
 | 
					                verticalAlignment = Alignment.CenterVertically,
 | 
				
			||||||
            ) {
 | 
					            ) {
 | 
				
			||||||
 | 
					                Icon(
 | 
				
			||||||
 | 
					                    painter = painterResource(Res.drawable.ic_table_24dp),
 | 
				
			||||||
 | 
					                    contentDescription = null,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                Text(
 | 
					                Text(
 | 
				
			||||||
                    modifier = Modifier.fillMaxWidth(),
 | 
					 | 
				
			||||||
                    overflow = TextOverflow.Ellipsis,
 | 
					                    overflow = TextOverflow.Ellipsis,
 | 
				
			||||||
                    textAlign = TextAlign.Start,
 | 
					                    textAlign = TextAlign.Start,
 | 
				
			||||||
                    maxLines = 1,
 | 
					                    maxLines = 1,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ import com.pixelized.desktop.lwa.screen.roll.DifficultyUio.Difficulty
 | 
				
			||||||
import com.pixelized.desktop.lwa.utils.DisableInteractionSource
 | 
					import com.pixelized.desktop.lwa.utils.DisableInteractionSource
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
					import lwacharactersheet.composeapp.generated.resources.Res
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp
 | 
					import lwacharactersheet.composeapp.generated.resources.ic_d20_24dp
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.roll_page__dc__label
 | 
					import lwacharactersheet.composeapp.generated.resources.roll_page__dc__label
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.roll_page__dc_easy__label
 | 
					import lwacharactersheet.composeapp.generated.resources.roll_page__dc_easy__label
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.roll_page__dc_hard__label
 | 
					import lwacharactersheet.composeapp.generated.resources.roll_page__dc_hard__label
 | 
				
			||||||
| 
						 | 
					@ -145,7 +145,7 @@ fun RollPage(
 | 
				
			||||||
                            this.rotationZ = viewModel.rollRotation.value
 | 
					                            this.rotationZ = viewModel.rollRotation.value
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                    tint = MaterialTheme.colors.primary,
 | 
					                    tint = MaterialTheme.colors.primary,
 | 
				
			||||||
                    painter = painterResource(Res.drawable.ic_d20_32dp),
 | 
					                    painter = painterResource(Res.drawable.ic_d20_24dp),
 | 
				
			||||||
                    contentDescription = null,
 | 
					                    contentDescription = null,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                AnimatedContent(
 | 
					                AnimatedContent(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,10 @@ class RollUseCaseTest {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun build1D100ResultSet(count: Int = ROLL_COUNT): List<Int> {
 | 
					    private fun build1D100ResultSet(count: Int = ROLL_COUNT): List<Int> {
 | 
				
			||||||
 | 
					        val useCase = RollUseCase()
 | 
				
			||||||
        val result = MutableList(100) { 0 }
 | 
					        val result = MutableList(100) { 0 }
 | 
				
			||||||
        repeat(count) {
 | 
					        repeat(count) {
 | 
				
			||||||
            val roll = RollUseCase.rollD100()
 | 
					            val roll = useCase.rollD100()
 | 
				
			||||||
            result[roll - 1] += 1
 | 
					            result[roll - 1] += 1
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return result
 | 
					        return result
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,12 @@
 | 
				
			||||||
package com.pixelized.desktop.lwa.business
 | 
					package com.pixelized.desktop.lwa.business
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize
 | 
					 | 
				
			||||||
import org.junit.Test
 | 
					import org.junit.Test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SkillNormalizerUseCaseText {
 | 
					class SkillNormalizerUseCaseText {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testNormalization() {
 | 
					    fun testNormalization() {
 | 
				
			||||||
 | 
					        val useCase = SkillNormalizerUseCase()
 | 
				
			||||||
        val samples = listOf(
 | 
					        val samples = listOf(
 | 
				
			||||||
            0 to 0,
 | 
					            0 to 0,
 | 
				
			||||||
            1 to 0,
 | 
					            1 to 0,
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ class SkillNormalizerUseCaseText {
 | 
				
			||||||
            10 to 10,
 | 
					            10 to 10,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        samples.forEach { (value, expected) ->
 | 
					        samples.forEach { (value, expected) ->
 | 
				
			||||||
            assert(normalize(value) == expected) {
 | 
					            assert(useCase.normalize(value) == expected) {
 | 
				
			||||||
                "$value should be normalized to $expected"
 | 
					                "$value should be normalized to $expected"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue